package com.mk.api.open.util;


import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author litianyi
 */

@Slf4j
public enum MktHttpUtil {


    /**
     * 实例对象
     */
    Instance;
    private OkHttpClient okHttpClient;
    private OkHttpClient.Builder builder;
    private static final int DEFAULT_TIMEOUT = 10;

    MktHttpUtil() {
        Dispatcher dispatcher = new Dispatcher();
        dispatcher.setMaxRequests(200);
        dispatcher.setMaxRequestsPerHost(200);

        this.builder = new OkHttpClient.Builder()
                .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                .readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                .writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                .dispatcher(dispatcher)
                .connectionPool(new ConnectionPool(10, 5, TimeUnit.MINUTES))
//                .addInterceptor(new RetryIntercepter(3))
                .retryOnConnectionFailure(true);
    }

    public OkHttpClient getOkHttpClient() {
        if (this.okHttpClient == null) {
            synchronized (Instance) {
                if (this.okHttpClient == null) {
                    this.okHttpClient = this.builder.build();
                }
            }
        }
        return this.okHttpClient;
    }

    /**
     * get 方法
     *
     * @param url
     * @return
     */
    public static String get(String url) {
        log.info("url={}", url);
        Response response = null;
        try {
            Request request = new Request.Builder().get().url(url).cacheControl(new CacheControl.Builder().noCache().build())
                    .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
                    .build();
            response = MktHttpUtil.Instance.getOkHttpClient().newCall(request).execute();
            if (response.isSuccessful()) {
                return response.body().string();
            }
        } catch (Exception e) {
            log.error("[MktHttpUtil.get]调用外部接口异常: url={}", url, e);
        } finally {
            if (Objects.nonNull(response) && Objects.nonNull(response.body())) {
                response.body().close();
            }
        }
        return null;
    }

    public static String postUrlEncode(String url, Map<String, Object> param) {
        log.info("url={},param={}", url, param);
        Response response = null;
        try {
            FormBody.Builder builder = new FormBody.Builder();
            param.forEach((key, value) -> {
                if (Objects.nonNull(value)) {
                    builder.add(key, String.valueOf(value));
                }
            });
            FormBody formBody = builder.build();
            Request request = new Request.Builder().post(formBody).url(url).build();
            response = MktHttpUtil.Instance.getOkHttpClient().newCall(request).execute();
            if (response.isSuccessful()) {
                return response.body().string();
            }
        } catch (Exception e) {
            log.error("[MktHttpUtil.postUrlEncode]调用外部接口异常: url={}", url, e);
        } finally {
            if (Objects.nonNull(response) && Objects.nonNull(response.body())) {
                response.body().close();
            }
        }
        return null;
    }


    /**
     * @param url
     * @return
     */
    public static String getJson(String url) {
        log.info("url={}", url);
        Response response = null;
        try {
            Request request = new Request.Builder().get().url(url).cacheControl(new CacheControl.Builder().noCache().build())
                    .addHeader("Content-Type", "application/json; charset=UTF-8")
                    .addHeader("Accept", "application/json")
                    .build();
            response = MktHttpUtil.Instance.getOkHttpClient().newCall(request).execute();
            if (response.isSuccessful()) {
                return response.body().string();
            }
        } catch (Exception e) {
            log.error("[MktHttpUtil.getJson]调用外部接口异常: url={}", url, e);
        } finally {
            if (Objects.nonNull(response) && Objects.nonNull(response.body())) {
                response.body().close();
            }
        }
        return null;
    }

    /**
     * post 方法
     *
     * @param url
     * @param param
     * @param header
     * @return
     */
    public static String post(String url, Map<String, String> param, Map<String, String> header) {
        log.info("url={},param={}", url, param);
        long startTime = System.currentTimeMillis();

        Response response = null;
        try {
            FormBody.Builder builder = new FormBody.Builder();

            for (Map.Entry<String, String> entry : param.entrySet()) {
                if (StringUtils.isBlank(entry.getKey()) || Objects.isNull(entry.getValue())) {
                    continue;
                }
                builder.add(entry.getKey(), entry.getValue());
            }
            RequestBody formBody = builder.build();
            Request.Builder requestBuilder = new Request.Builder().post(formBody).url(url).cacheControl(new CacheControl.Builder().noCache().build());
            if (header != null && !header.isEmpty()) {
                header.forEach(requestBuilder::addHeader);
            }
            Request request = requestBuilder.build();

            response = MktHttpUtil.Instance.getOkHttpClient().newCall(request).execute();
            if (response.isSuccessful()) {
                return response.body().string();
            }
        } catch (Exception e) {
            log.error("[MktHttpUtil.post]调用外部接口异常: url={}, param={}", url,param, e);
        } finally {
            if (Objects.nonNull(response) && Objects.nonNull(response.body())) {
                response.body().close();
            }
            long endTime = System.currentTimeMillis();
            log.info("url={},time={}ms", url, (endTime - startTime));
        }
        return null;
    }

    /**
     * post 方法
     *
     * @param url
     * @param json
     * @return
     */
    public static String postJson(String url, String json) {
        log.info("url={},json={}", url, json);
        long startTime = System.currentTimeMillis();
        Response response = null;
        try {
            Request request = new Request.Builder().url(url).cacheControl(new CacheControl.Builder().noCache().build()).post(RequestBody.create(
                    MediaType.parse("application/json; charset=utf-8"),
                    json))
                    .build();

            response = MktHttpUtil.Instance.getOkHttpClient().newCall(request).execute();
            if (response.isSuccessful()) {
                return response.body().string();
            }
        } catch (Exception e) {
            log.error("[MktHttpUtil.postJson]调用外部接口异常: url={}, param={}", url,json, e);
        } finally {
            if (Objects.nonNull(response) && Objects.nonNull(response.body())) {
                response.body().close();
            }
            long endTime = System.currentTimeMillis();
            log.info("url={},time={},ms", url, (endTime - startTime));
        }
        return null;
    }

    /**
     * 抖音开放平台服务
     *
     * @param url
     * @param json
     * @return
     */
    public static String postJsonForDy(String url, String json) {
        long startTime = System.currentTimeMillis();
        String timestamp = String.valueOf(startTime / 1000);
        Response response = null;
        try {
            Request request = new Request.Builder().url(url).cacheControl(new CacheControl.Builder().noCache().build()).post(RequestBody.create(
                    MediaType.parse("application/json; charset=utf-8"),
                    json)).build();
            response = MktHttpUtil.Instance.getOkHttpClient().newCall(request).execute();
            if (response.isSuccessful()) {
                return response.body().string();
            }
        } catch (Exception e) {
            log.error("[MktHttpUtil.postJsonForDy]调用外部接口异常: url={}, param={}", url,json, e);
        } finally {
            if (Objects.nonNull(response) && Objects.nonNull(response.body())) {
                response.body().close();
            }
            long endTime = System.currentTimeMillis();
            log.info("请求接口URL={},耗时={},ms", url, (endTime - startTime));
        }
        return null;
    }




}
